/* This file contains the definitions and documentation for the goal functions
   used in the Superoptimizer.

   Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any
   later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; see the file COPYING.  If not, write to the Free
   Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */

/* The fields in the cpp macro call "DEF_GOAL()" are:

   1. The internal name of the goal function.

   2. The number of input operands.

   3. The printed name of the instruction.

   4. C code that implements the function.

   */

DEF_GOAL (EQ,             2, "eq",          { r = v0 == v1; })
DEF_GOAL (NE,             2, "ne",          { r = v0 != v1; })
DEF_GOAL (LES,            2, "les",         { r = (signed_word) v0 <= (signed_word) v1; })
DEF_GOAL (GES,            2, "ges",         { r = (signed_word) v0 >= (signed_word) v1; })
DEF_GOAL (LTS,            2, "lts",         { r = (signed_word) v0 < (signed_word) v1; })
DEF_GOAL (GTS,            2, "gts",         { r = (signed_word) v0 > (signed_word) v1; })
DEF_GOAL (LEU,            2, "leu",         { r = (unsigned_word) v0 <= (unsigned_word) v1; })
DEF_GOAL (GEU,            2, "geu",         { r = (unsigned_word) v0 >= (unsigned_word) v1; })
DEF_GOAL (LTU,            2, "ltu",         { r = (unsigned_word) v0 < (unsigned_word) v1; })
DEF_GOAL (GTU,            2, "gtu",         { r = (unsigned_word) v0 > (unsigned_word) v1; })
DEF_GOAL (LESU,           2, "lesu",        { r = (signed_word) v0 < 0 || (unsigned_word) v0 <= (unsigned_word) v1; })
DEF_GOAL (GESU,           2, "gesu",        { r = (signed_word) v0 >= 0 && (unsigned_word) v0 >= (unsigned_word) v1; })
DEF_GOAL (LTSU,           2, "ltsu",        { r = (signed_word) v0 < 0 || (unsigned_word) v0 < (unsigned_word) v1; })
DEF_GOAL (GTSU,           2, "gtsu",        { r = (signed_word) v0 >= 0 && (unsigned_word) v0 > (unsigned_word) v1; })

DEF_GOAL (EQ0,            1, "eq0",         { r = v0 == 0; })
DEF_GOAL (NE0,            1, "ne0",         { r = v0 != 0; })
DEF_GOAL (LES0,           1, "les0",        { r = (signed_word) v0 <= 0; })
DEF_GOAL (GES0,           1, "ges0",        { r = (signed_word) v0 >= 0; })
DEF_GOAL (LTS0,           1, "lts0",        { r = (signed_word) v0 < 0; })
DEF_GOAL (GTS0,           1, "gts0",        { r = (signed_word) v0 > 0; })

DEF_GOAL (NEQ,            2, "neq",         { r = -(v0 == v1); })
DEF_GOAL (NNE,            2, "nne",         { r = -(v0 != v1); })
DEF_GOAL (NLES,           2, "nles",        { r = -((signed_word) v0 <= (signed_word) v1); })
DEF_GOAL (NGES,           2, "nges",        { r = -((signed_word) v0 >= (signed_word) v1); })
DEF_GOAL (NLTS,           2, "nlts",        { r = -((signed_word) v0 < (signed_word) v1); })
DEF_GOAL (NGTS,           2, "ngts",        { r = -((signed_word) v0 > (signed_word) v1); })
DEF_GOAL (NLEU,           2, "nleu",        { r = -((unsigned_word) v0 <= (unsigned_word) v1); })
DEF_GOAL (NGEU,           2, "ngeu",        { r = -((unsigned_word) v0 >= (unsigned_word) v1); })
DEF_GOAL (NLTU,           2, "nltu",        { r = -((unsigned_word) v0 < (unsigned_word) v1); })
DEF_GOAL (NGTU,           2, "ngtu",        { r = -((unsigned_word) v0 > (unsigned_word) v1); })

DEF_GOAL (NEQ0,           1, "neq0",        { r = -(v0 == 0); })
DEF_GOAL (NNE0,           1, "nne0",        { r = -(v0 != 0); })
DEF_GOAL (NLES0,          1, "nles0",       { r = -((signed_word) v0 <= 0); })
DEF_GOAL (NGES0,          1, "nges0",       { r = -((signed_word) v0 >= 0); })
DEF_GOAL (NLTS0,          1, "nlts0",       { r = -((signed_word) v0 < 0); })
DEF_GOAL (NGTS0,          1, "ngts0",       { r = -((signed_word) v0 > 0); })

DEF_GOAL (EQ80000000,            2, "eq80000000",         { r = 0x80000000 & -(v0 == v1); })
DEF_GOAL (NE80000000,            2, "ne80000000",         { r = 0x80000000 & -(v0 != v1); })
DEF_GOAL (LES80000000,           2, "les80000000",        { r = 0x80000000 & -((signed_word) v0 <= (signed_word) v1); })
DEF_GOAL (GES80000000,    2, "ges80000000",   { r = 0x80000000 & -((signed_word) v0 >= (signed_word) v1); })
DEF_GOAL (LTS80000000,    2, "lts80000000",   { r = 0x80000000 & -((signed_word) v0 < (signed_word) v1); })
DEF_GOAL (GTS80000000,    2, "gts80000000",   { r = 0x80000000 & -((signed_word) v0 > (signed_word) v1); })
DEF_GOAL (LEU80000000,    2, "leu80000000",   { r = 0x80000000 & -((unsigned_word) v0 <= (unsigned_word) v1); })
DEF_GOAL (GEU80000000,    2, "geu80000000",   { r = 0x80000000 & -((unsigned_word) v0 >= (unsigned_word) v1); })
DEF_GOAL (LTU80000000,    2, "ltu80000000",   { r = 0x80000000 & -((unsigned_word) v0 < (unsigned_word) v1); })
DEF_GOAL (GTU80000000,    2, "gtu80000000",   { r = 0x80000000 & -((unsigned_word) v0 > (unsigned_word) v1); })

DEF_GOAL (EQ080000000,    1, "eq080000000",   { r = 0x80000000 & -(v0 == 0); })
DEF_GOAL (NE080000000,    1, "ne080000000",   { r = 0x80000000 & -(v0 != 0); })
DEF_GOAL (LES080000000,   1, "les080000000",  { r = 0x80000000 & -((signed_word) v0 <= 0); })
DEF_GOAL (GES080000000,   1, "ges080000000",  { r = 0x80000000 & -((signed_word) v0 >= 0); })
DEF_GOAL (LTS080000000,   1, "lts080000000",  { r = 0x80000000 & -((signed_word) v0 < 0); })
DEF_GOAL (GTS080000000,   1, "gts080000000",  { r = 0x80000000 & -((signed_word) v0 > 0); })

DEF_GOAL (MAXS,           2, "maxs",        { r = (signed_word) v0 > (signed_word) v1 ? v0 : v1; })
DEF_GOAL (MINS,           2, "mins",        { r = (signed_word) v0 < (signed_word) v1 ? v0 : v1; })
DEF_GOAL (MAXU,           2, "maxu",        { r = (unsigned_word) v0 > (unsigned_word) v1 ? v0 : v1; })
DEF_GOAL (MINU,           2, "minu",        { r = (unsigned_word) v0 < (unsigned_word) v1 ? v0 : v1; })
DEF_GOAL (CMPS,           2, "cmps",        { r = (signed_word) v0 > (signed_word) v1? 1 : ((signed_word) v0 < (signed_word) v1 ? -1 : 0); })
DEF_GOAL (CMPU,           2, "cmpu",        { r = (unsigned_word) v0 > (unsigned_word) v1? 1 : ((unsigned_word) v0 < (unsigned_word) v1 ? -1 : 0); })
DEF_GOAL (SGN,            1, "sgn",         { r = (signed_word) v0 > 0 ? 1 : ((signed_word) v0 < 0 ? -1 : 0); })
DEF_GOAL (ABS,            1, "abs",         { r = (signed_word) v0 < 0 ? -v0 : v0; })
DEF_GOAL (NABS,           1, "nabs",        { r = (signed_word) v0 > 0 ? -v0 : v0; })
DEF_GOAL (GRAY,           1, "gray",        { r = ((~(v0 ^ (v0 << 1)) & (-1 << 31)) | ((v0 << 1) & ~(-1 << 31)) | (v0 >> 31)); })
DEF_GOAL (GRAY2,          1, "gray2",       { v0 = ((~(v0 ^ (v0 << 1)) & (-1 << 31)) | ((v0 << 1) & ~(-1 << 31)) | (v0 >> 31)); r = ((~(v0 ^ (v0 << 1)) & (-1 << 31)) | ((v0 << 1) & ~(-1 << 31)) | (v0 >> 31)); })
DEF_GOAL (DIVIDE_BY_2,    1, "divide_by_2", { r = (signed_word) v0 / 2; })
DEF_GOAL (DIVIDE_BY_4,    1, "divide_by_4", { r = (signed_word) v0 / 4; })
DEF_GOAL (DIVIDE_BY_2e30,    1, "divide_by_2e30", { r = (signed_word) v0 / (1<<30); })
DEF_GOAL (MOD_BY_2,    1, "mod_by_2", { r = (signed_word) v0 % 2; })
DEF_GOAL (MOD_BY_4,    1, "mod_by_4", { r = (signed_word) v0 % 4; })
DEF_GOAL (MOD_BY_2e30,    1, "mod_by_2e30", { r = (signed_word) v0 % (1<<30); })

DEF_GOAL (EQ_PLUS,        3, "eq+",         { r = (v0 == v1) + v2; })
DEF_GOAL (NE_PLUS,        3, "ne+",         { r = (v0 != v1) + v2; })
DEF_GOAL (LES_PLUS,       3, "les+",        { r = ((signed_word) v0 <= (signed_word) v1) + v2; })
DEF_GOAL (GES_PLUS,       3, "ges+",        { r = ((signed_word) v0 >= (signed_word) v1) + v2; })
DEF_GOAL (LTS_PLUS,       3, "lts+",        { r = ((signed_word) v0 < (signed_word) v1) + v2; })
DEF_GOAL (GTS_PLUS,       3, "gts+",        { r = ((signed_word) v0 > (signed_word) v1) + v2; })
DEF_GOAL (LEU_PLUS,       3, "leu+",        { r = ((unsigned_word) v0 <= (unsigned_word) v1) + v2; })
DEF_GOAL (GEU_PLUS,       3, "geu+",        { r = ((unsigned_word) v0 >= (unsigned_word) v1) + v2; })
DEF_GOAL (LTU_PLUS,       3, "ltu+",        { r = ((unsigned_word) v0 < (unsigned_word) v1) + v2; })
DEF_GOAL (GTU_PLUS,       3, "gtu+",        { r = ((unsigned_word) v0 > (unsigned_word) v1) + v2; })
DEF_GOAL (LESU_PLUS,      3, "lesu+",       { r = ((signed_word) v0 < 0 || (unsigned_word) v0 <= (unsigned_word) v1) + v2; })
DEF_GOAL (GESU_PLUS,      3, "gesu+",       { r = ((signed_word) v0 >= 0 && (unsigned_word) v0 >= (unsigned_word) v1) + v2; })
DEF_GOAL (LTSU_PLUS,      3, "ltsu+",       { r = ((signed_word) v0 < 0 || (unsigned_word) v0 < (unsigned_word) v1) + v2; })
DEF_GOAL (GTSU_PLUS,      3, "gtsu+",       { r = ((signed_word) v0 >= 0 && (unsigned_word) v0 > (unsigned_word) v1) + v2; })
DEF_GOAL (EQ0_PLUS,       2, "eq0+",        { r = (v0 == 0) + v1; })
DEF_GOAL (NE0_PLUS,       2, "ne0+",        { r = (v0 != 0) + v1; })
DEF_GOAL (LES0_PLUS,      2, "les0+",       { r = ((signed_word) v0 <= 0) + v1; })
DEF_GOAL (GES0_PLUS,      2, "ges0+",       { r = ((signed_word) v0 >= 0) + v1; })
DEF_GOAL (LTS0_PLUS,      2, "lts0+",       { r = ((signed_word) v0 < 0) + v1; })
DEF_GOAL (GTS0_PLUS,      2, "gts0+",       { r = ((signed_word) v0 > 0) + v1; })

DEF_SYNONYM (EQ_PLUS,        "peq")
DEF_SYNONYM (NE_PLUS,        "pne")
DEF_SYNONYM (LES_PLUS,       "ples")
DEF_SYNONYM (GES_PLUS,       "pges")
DEF_SYNONYM (LTS_PLUS,       "plts")
DEF_SYNONYM (GTS_PLUS,       "pgts")
DEF_SYNONYM (LEU_PLUS,       "pleu")
DEF_SYNONYM (GEU_PLUS,       "pgeu")
DEF_SYNONYM (LTU_PLUS,       "pltu")
DEF_SYNONYM (GTU_PLUS,       "pgtu")
DEF_SYNONYM (LESU_PLUS,      "plesu")
DEF_SYNONYM (GESU_PLUS,      "pgesu")
DEF_SYNONYM (LTSU_PLUS,      "pltsu")
DEF_SYNONYM (GTSU_PLUS,      "pgtsu")
DEF_SYNONYM (EQ0_PLUS,       "peq0")
DEF_SYNONYM (NE0_PLUS,       "pne0")
DEF_SYNONYM (LES0_PLUS,      "ples0")
DEF_SYNONYM (GES0_PLUS,      "pges0")
DEF_SYNONYM (LTS0_PLUS,      "plts0")
DEF_SYNONYM (GTS0_PLUS,      "pgts0")

DEF_GOAL (EQ_MINUS,       3, "eq-",         { r = v2 - (v0 == v1); })
DEF_GOAL (NE_MINUS,       3, "ne-",         { r = v2 - (v0 != v1); })
DEF_GOAL (LES_MINUS,      3, "les-",        { r = v2 - ((signed_word) v0 <= (signed_word) v1); })
DEF_GOAL (GES_MINUS,      3, "ges-",        { r = v2 - ((signed_word) v0 >= (signed_word) v1); })
DEF_GOAL (LTS_MINUS,      3, "lts-",        { r = v2 - ((signed_word) v0 < (signed_word) v1); })
DEF_GOAL (GTS_MINUS,      3, "gts-",        { r = v2 - ((signed_word) v0 > (signed_word) v1); })
DEF_GOAL (LEU_MINUS,      3, "leu-",        { r = v2 - ((unsigned_word) v0 <= (unsigned_word) v1); })
DEF_GOAL (GEU_MINUS,      3, "geu-",        { r = v2 - ((unsigned_word) v0 >= (unsigned_word) v1); })
DEF_GOAL (LTU_MINUS,      3, "ltu-",        { r = v2 - ((unsigned_word) v0 < (unsigned_word) v1); })
DEF_GOAL (GTU_MINUS,      3, "gtu-",        { r = v2 - ((unsigned_word) v0 > (unsigned_word) v1); })
DEF_GOAL (LESU_MINUS,     3, "lesu-",       { r = v2 - ((signed_word) v0 < 0 || (unsigned_word) v0 <= (unsigned_word) v1); })
DEF_GOAL (GESU_MINUS,     3, "gesu-",       { r = v2 - ((signed_word) v0 >= 0 && (unsigned_word) v0 >= (unsigned_word) v1); })
DEF_GOAL (LTSU_MINUS,     3, "ltsu-",       { r = v2 - ((signed_word) v0 < 0 || (unsigned_word) v0 < (unsigned_word) v1); })
DEF_GOAL (GTSU_MINUS,     3, "gtsu-",       { r = v2 - ((signed_word) v0 >= 0 && (unsigned_word) v0 > (unsigned_word) v1); })

DEF_GOAL (EQ0_MINUS,      2, "eq0-",        { r = v1 - (v0 == 0); })
DEF_GOAL (NE0_MINUS,      2, "ne0-",        { r = v1 - (v0 != 0); })
DEF_GOAL (LES0_MINUS,     2, "les0-",       { r = v1 - ((signed_word) v0 <= 0); })
DEF_GOAL (GES0_MINUS,     2, "ges0-",       { r = v1 - ((signed_word) v0 >= 0); })
DEF_GOAL (LTS0_MINUS,     2, "lts0-",       { r = v1 - ((signed_word) v0 < 0); })
DEF_GOAL (GTS0_MINUS,     2, "gts0-",       { r = v1 - ((signed_word) v0 > 0); })

DEF_GOAL (NEQ_AND,        3, "naeq",        { r = -(v0 == v1) & v2; })
DEF_GOAL (NNE_AND,        3, "nane",        { r = -(v0 != v1) & v2; })
DEF_GOAL (NLES_AND,       3, "nales",       { r = -((signed_word) v0 <= (signed_word) v1) & v2; })
DEF_GOAL (NGES_AND,       3, "nages",       { r = -((signed_word) v0 >= (signed_word) v1) & v2; })
DEF_GOAL (NLTS_AND,       3, "nalts",       { r = -((signed_word) v0 < (signed_word) v1) & v2; })
DEF_GOAL (NGTS_AND,       3, "nagts",       { r = -((signed_word) v0 > (signed_word) v1) & v2; })
DEF_GOAL (NLEU_AND,       3, "naleu",       { r = -((unsigned_word) v0 <= (unsigned_word) v1) & v2; })
DEF_GOAL (NGEU_AND,       3, "nageu",       { r = -((unsigned_word) v0 >= (unsigned_word) v1) & v2; })
DEF_GOAL (NLTU_AND,       3, "naltu",       { r = -((unsigned_word) v0 < (unsigned_word) v1) & v2; })
DEF_GOAL (NGTU_AND,       3, "nagtu",       { r = -((unsigned_word) v0 > (unsigned_word) v1) & v2; })

DEF_GOAL (NEQ0_AND,       2, "naeq0",       { r = -(v0 == 0) & v1; })
DEF_GOAL (NNE0_AND,       2, "nane0",       { r = -(v0 != 0) & v1; })
DEF_GOAL (NLES0_AND,      2, "nales0",      { r = -((signed_word) v0 <= 0) & v1; })
DEF_GOAL (NGES0_AND,      2, "nages0",      { r = -((signed_word) v0 >= 0) & v1; })
DEF_GOAL (NLTS0_AND,      2, "nalts0",      { r = -((signed_word) v0 < 0) & v1; })
DEF_GOAL (NGTS0_AND,      2, "nagts0",      { r = -((signed_word) v0 > 0) & v1; })

/* Don't do all variants here, since it is trivial to deduce the rest.  */
DEF_GOAL (EQ_SEL,       4, "eq-sel",         { r = (v0 == v1) ? v2 : v3; })
DEF_GOAL (LES_SEL,      4, "les-sel",        { r = ((signed_word) v0 <= (signed_word) v1) ? v2 : v3; })
DEF_GOAL (LTS_SEL,      4, "lts-sel",        { r = ((signed_word) v0 < (signed_word) v1) ? v2 : v3; })
DEF_GOAL (LEU_SEL,      4, "leu-sel",        { r = ((unsigned_word) v0 <= (unsigned_word) v1) ? v2 : v3; })
DEF_GOAL (LTU_SEL,      4, "ltu-sel",        { r = ((unsigned_word) v0 < (unsigned_word) v1) ? v2 : v3; })

DEF_GOAL (EQ0_SEL,      3, "eq0-sel",        { r = (v0 == 0) ? v1 : v2; })
DEF_GOAL (LES0_SEL,     3, "les0-sel",       { r = ((signed_word) v0 <= 0) ? v1 : v2; })
DEF_GOAL (LTS0_SEL,     3, "lts0-sel",       { r = ((signed_word) v0 < 0) ? v1 : v2; })

DEF_GOAL (FFS,            1, "ffs",         { r = ffs_internal (v0); })
DEF_GOAL (CLOG2,          1, "ceil_log2",   { r = ceil_log2 (v0); })
DEF_GOAL (FLOG2,          1, "floor_log2",   { r = floor_log2 (v0); })
DEF_GOAL (MULTADJ,        3, "multadj",     { r = v1 + ((signed_word) v0 < 0 ? v2 : 0); })

DEF_GOAL (SHIFTL_1, 1, "sll1", { r = v0 << 1; })
DEF_GOAL (SHIFTL_2, 1, "sll2", { r = v0 << 2; })
DEF_GOAL (SHIFTL_3, 1, "sll3", { r = v0 << 3; })
DEF_GOAL (SHIFTL_4, 1, "sll4", { r = v0 << 4; })
DEF_GOAL (SHIFTL_5, 1, "sll5", { r = v0 << 5; })
DEF_GOAL (SHIFTL_6, 1, "sll6", { r = v0 << 6; })
DEF_GOAL (SHIFTL_7, 1, "sll7", { r = v0 << 7; })
DEF_GOAL (SHIFTL_8, 1, "sll8", { r = v0 << 8; })
DEF_GOAL (SHIFTL_9, 1, "sll9", { r = v0 << 9; })
DEF_GOAL (SHIFTL_10, 1, "sll10", { r = v0 << 10; })
DEF_GOAL (SHIFTL_11, 1, "sll11", { r = v0 << 11; })
DEF_GOAL (SHIFTL_12, 1, "sll12", { r = v0 << 12; })
DEF_GOAL (SHIFTL_13, 1, "sll13", { r = v0 << 13; })
DEF_GOAL (SHIFTL_14, 1, "sll14", { r = v0 << 14; })
DEF_GOAL (SHIFTL_15, 1, "sll15", { r = v0 << 15; })
DEF_GOAL (SHIFTL_16, 1, "sll16", { r = v0 << 16; })
DEF_GOAL (SHIFTL_17, 1, "sll17", { r = v0 << 17; })
DEF_GOAL (SHIFTL_18, 1, "sll18", { r = v0 << 18; })
DEF_GOAL (SHIFTL_19, 1, "sll19", { r = v0 << 19; })
DEF_GOAL (SHIFTL_20, 1, "sll20", { r = v0 << 20; })
DEF_GOAL (SHIFTL_21, 1, "sll21", { r = v0 << 21; })
DEF_GOAL (SHIFTL_22, 1, "sll22", { r = v0 << 22; })
DEF_GOAL (SHIFTL_23, 1, "sll23", { r = v0 << 23; })
DEF_GOAL (SHIFTL_24, 1, "sll24", { r = v0 << 24; })
DEF_GOAL (SHIFTL_25, 1, "sll25", { r = v0 << 25; })
DEF_GOAL (SHIFTL_26, 1, "sll26", { r = v0 << 26; })
DEF_GOAL (SHIFTL_27, 1, "sll27", { r = v0 << 27; })
DEF_GOAL (SHIFTL_28, 1, "sll28", { r = v0 << 28; })
DEF_GOAL (SHIFTL_29, 1, "sll29", { r = v0 << 29; })
DEF_GOAL (SHIFTL_30, 1, "sll30", { r = v0 << 30; })
DEF_GOAL (SHIFTL_31, 1, "sll31", { r = v0 << 31; })

DEF_GOAL (LSHIFTR_1, 1, "srl1", { r = v0 >> 1; })
DEF_GOAL (LSHIFTR_2, 1, "srl2", { r = v0 >> 2; })
DEF_GOAL (LSHIFTR_3, 1, "srl3", { r = v0 >> 3; })
DEF_GOAL (LSHIFTR_4, 1, "srl4", { r = v0 >> 4; })
DEF_GOAL (LSHIFTR_5, 1, "srl5", { r = v0 >> 5; })
DEF_GOAL (LSHIFTR_6, 1, "srl6", { r = v0 >> 6; })
DEF_GOAL (LSHIFTR_7, 1, "srl7", { r = v0 >> 7; })
DEF_GOAL (LSHIFTR_8, 1, "srl8", { r = v0 >> 8; })
DEF_GOAL (LSHIFTR_9, 1, "srl9", { r = v0 >> 9; })
DEF_GOAL (LSHIFTR_10, 1, "srl10", { r = v0 >> 10; })
DEF_GOAL (LSHIFTR_11, 1, "srl11", { r = v0 >> 11; })
DEF_GOAL (LSHIFTR_12, 1, "srl12", { r = v0 >> 12; })
DEF_GOAL (LSHIFTR_13, 1, "srl13", { r = v0 >> 13; })
DEF_GOAL (LSHIFTR_14, 1, "srl14", { r = v0 >> 14; })
DEF_GOAL (LSHIFTR_15, 1, "srl15", { r = v0 >> 15; })
DEF_GOAL (LSHIFTR_16, 1, "srl16", { r = v0 >> 16; })
DEF_GOAL (LSHIFTR_17, 1, "srl17", { r = v0 >> 17; })
DEF_GOAL (LSHIFTR_18, 1, "srl18", { r = v0 >> 18; })
DEF_GOAL (LSHIFTR_19, 1, "srl19", { r = v0 >> 19; })
DEF_GOAL (LSHIFTR_20, 1, "srl20", { r = v0 >> 20; })
DEF_GOAL (LSHIFTR_21, 1, "srl21", { r = v0 >> 21; })
DEF_GOAL (LSHIFTR_22, 1, "srl22", { r = v0 >> 22; })
DEF_GOAL (LSHIFTR_23, 1, "srl23", { r = v0 >> 23; })
DEF_GOAL (LSHIFTR_24, 1, "srl24", { r = v0 >> 24; })
DEF_GOAL (LSHIFTR_25, 1, "srl25", { r = v0 >> 25; })
DEF_GOAL (LSHIFTR_26, 1, "srl26", { r = v0 >> 26; })
DEF_GOAL (LSHIFTR_27, 1, "srl27", { r = v0 >> 27; })
DEF_GOAL (LSHIFTR_28, 1, "srl28", { r = v0 >> 28; })
DEF_GOAL (LSHIFTR_29, 1, "srl29", { r = v0 >> 29; })
DEF_GOAL (LSHIFTR_30, 1, "srl30", { r = v0 >> 30; })
DEF_GOAL (LSHIFTR_31, 1, "srl31", { r = v0 >> 31; })

DEF_GOAL (ASHIFTR_1, 1, "sra1", { r = (signed_word) v0 >> 1; })
DEF_GOAL (ASHIFTR_2, 1, "sra2", { r = (signed_word) v0 >> 2; })
DEF_GOAL (ASHIFTR_3, 1, "sra3", { r = (signed_word) v0 >> 3; })
DEF_GOAL (ASHIFTR_4, 1, "sra4", { r = (signed_word) v0 >> 4; })
DEF_GOAL (ASHIFTR_5, 1, "sra5", { r = (signed_word) v0 >> 5; })
DEF_GOAL (ASHIFTR_6, 1, "sra6", { r = (signed_word) v0 >> 6; })
DEF_GOAL (ASHIFTR_7, 1, "sra7", { r = (signed_word) v0 >> 7; })
DEF_GOAL (ASHIFTR_8, 1, "sra8", { r = (signed_word) v0 >> 8; })
DEF_GOAL (ASHIFTR_9, 1, "sra9", { r = (signed_word) v0 >> 9; })
DEF_GOAL (ASHIFTR_10, 1, "sra10", { r = (signed_word) v0 >> 10; })
DEF_GOAL (ASHIFTR_11, 1, "sra11", { r = (signed_word) v0 >> 11; })
DEF_GOAL (ASHIFTR_12, 1, "sra12", { r = (signed_word) v0 >> 12; })
DEF_GOAL (ASHIFTR_13, 1, "sra13", { r = (signed_word) v0 >> 13; })
DEF_GOAL (ASHIFTR_14, 1, "sra14", { r = (signed_word) v0 >> 14; })
DEF_GOAL (ASHIFTR_15, 1, "sra15", { r = (signed_word) v0 >> 15; })
DEF_GOAL (ASHIFTR_16, 1, "sra16", { r = (signed_word) v0 >> 16; })
DEF_GOAL (ASHIFTR_17, 1, "sra17", { r = (signed_word) v0 >> 17; })
DEF_GOAL (ASHIFTR_18, 1, "sra18", { r = (signed_word) v0 >> 18; })
DEF_GOAL (ASHIFTR_19, 1, "sra19", { r = (signed_word) v0 >> 19; })
DEF_GOAL (ASHIFTR_20, 1, "sra20", { r = (signed_word) v0 >> 20; })
DEF_GOAL (ASHIFTR_21, 1, "sra21", { r = (signed_word) v0 >> 21; })
DEF_GOAL (ASHIFTR_22, 1, "sra22", { r = (signed_word) v0 >> 22; })
DEF_GOAL (ASHIFTR_23, 1, "sra23", { r = (signed_word) v0 >> 23; })
DEF_GOAL (ASHIFTR_24, 1, "sra24", { r = (signed_word) v0 >> 24; })
DEF_GOAL (ASHIFTR_25, 1, "sra25", { r = (signed_word) v0 >> 25; })
DEF_GOAL (ASHIFTR_26, 1, "sra26", { r = (signed_word) v0 >> 26; })
DEF_GOAL (ASHIFTR_27, 1, "sra27", { r = (signed_word) v0 >> 27; })
DEF_GOAL (ASHIFTR_28, 1, "sra28", { r = (signed_word) v0 >> 28; })
DEF_GOAL (ASHIFTR_29, 1, "sra29", { r = (signed_word) v0 >> 29; })
DEF_GOAL (ASHIFTR_30, 1, "sra30", { r = (signed_word) v0 >> 30; })
DEF_GOAL (ASHIFTR_31, 1, "sra31", { r = (signed_word) v0 >> 31; })


DEF_GOAL (CMPBYTES,	2, "cmpbytes",
  {
    union { word w; char b[4]; } __r1;
    union { word w; char b[4]; } __r2;
    __r1.w = (v0); __r2.w = (v1);
    r = ((__r1.b[0] != __r2.b[0]) && (__r1.b[1] != __r2.b[1])
	 && (__r1.b[2] != __r2.b[2]) && (__r1.b[3] != __r2.b[3]));
  })

#ifdef __GNUC__
#if 0
DEF_GOAL (UDIV_QRNND,     3, "udiv_qrnnd",  ({ word t1, t2; udiv_qrnnd (t1, t2, v0, v1, v2); r = t1; }))
DEF_GOAL (UMOD_QRNND,     3, "umod_qrnnd",  ({ word t1, t2; udiv_qrnnd (t1, t2, v0, v1, v2); r = t2; }))
#endif
DEF_GOAL (UMULH,     2, "umulh",  ({ word t1; word t2; umul_ppmm (t1, t2, v0, v1); r = t1; }))
DEF_GOAL (UMULH3,     1, "umulh3",  ({ word t1; word t2; umul_ppmm (t1, t2, v0, 3); r = t1; }))
DEF_GOAL (UMULH5,     1, "umulh5",  ({ word t1; word t2; umul_ppmm (t1, t2, v0, 5); r = t1; }))
DEF_GOAL (UMULH6,     1, "umulh6",  ({ word t1; word t2; umul_ppmm (t1, t2, v0, 6); r = t1; }))
DEF_GOAL (UMULH7,     1, "umulh7",  ({ word t1; word t2; umul_ppmm (t1, t2, v0, 7); r = t1; }))
DEF_GOAL (UMULH9,     1, "umulh9",  ({ word t1; word t2; umul_ppmm (t1, t2, v0, 9); r = t1; }))
DEF_GOAL (UMULH10,     1, "umulh10",  ({ word t1; word t2; umul_ppmm (t1, t2, v0, 10); r = t1; }))
DEF_GOAL (UMULH11,     1, "umulh11",  ({ word t1; word t2; umul_ppmm (t1, t2, v0, 11); r = t1; }))
#endif /* __GNUC__ */

#ifdef __GNUC__
DEF_GOAL (MORE_EVEN,     2, "more_even",  ({ r = (v0 & -v0) > (v1 & -v1) ; }))
#endif /* __GNUC__ */
DEF_GOAL (CLEAR_LSB,	1, "clear_lsb", { r = v0 & ~(v0 & -v0); })
DEF_GOAL (CLEAR_LSB2,	2, "clear_lsb2", { r = v1 & ~(v0 & -v0); })

#if 0
DEF_GOAL (UDIV,           2, "udiv",        { r = v0 / v1; })
#endif

/* After "v0 = v1 + v2", compute if we got signed overflow.  */
DEF_GOAL (OVERFLOW_AFTER_ADD, 3, "add_ovfl",  { r = (signed_word) (~(v1 ^ v2) & (v0 ^ v1)) < 0; })

/* The most and least significant bits of a double word left shift.  */
DEF_GOAL (DBL_SHIFT_HI, 3, "dbl_shift_hi",
	  { r = (v2 >= BITS_PER_WORD
		 ? v0 << (v2 - BITS_PER_WORD)
		 : (v1 << v2) | (v0 >> (BITS_PER_WORD - v2))); })
DEF_GOAL (DBL_SHIFT_LO, 2, "dbl_shift_lo",
	  { r = (v1 >= BITS_PER_WORD
		 ? 0
		 : v0 << v1); })
DEF_GOAL (DBL_SHIFT_HI_TRUNC, 3, "dbl_shift_hi_trunc",
	  { r = ((v2 & 2*BITS_PER_WORD-1) >= BITS_PER_WORD
		 ? v0 << ((v2 & 2*BITS_PER_WORD-1) - BITS_PER_WORD)
		 : (v1 << (v2 & 2*BITS_PER_WORD-1)) | (v0 >> (BITS_PER_WORD - (v2 & 2*BITS_PER_WORD-1)))); })
DEF_GOAL (DBL_SHIFT_LO_TRUNC, 2, "dbl_shift_lo_trunc",
	  { r = ((v1 & 2*BITS_PER_WORD-1) >= BITS_PER_WORD
		 ? 0
		 : v0 << (v1 & 2*BITS_PER_WORD-1)); })

/*
Local variables:
mode:c
version-control: t
End:
*/
